//References.
import Utility.StringUtils;

import mx.collections.ArrayCollection;
import mx.controls.Alert;
import mx.core.Application;

//Variables.
private var serviceUrl:String;
private var folderPath:String;
private var maxFileSize:int;
private var maxFileNumber:int;
private var fileReferences:FileReferenceList = new FileReferenceList();
private var fileFilters:Array;
//Bindable variables.
[Bindable]public var fileList:ArrayCollection = new ArrayCollection();

//Function for setting initial properties and events.
public function init(): void{
	//Get service url from flashVars.
	serviceUrl = Application.application.parameters.serviceUrl;
	folderPath = Application.application.parameters.folderPath;
	maxFileSize = Application.application.parameters.maxFileSize;
	maxFileNumber = Application.application.parameters.maxFileNumber;
	panel.title = resourceManager.getString("Resources","UploadFolder") + ": " + folderPath;
	//Diable controls.
	upload.enabled = false;
	//Set event listeners for controls.
    choose.addEventListener(MouseEvent.CLICK, chooseFiles);
    removeall.addEventListener(MouseEvent.CLICK, removeAllFromList);
    fileReferences.addEventListener(Event.SELECT, addFilesToList);
    upload.addEventListener(MouseEvent.CLICK, uploadFiles);
}

//Search function for ArrayCollection.
static public function getItemIndexByProperty(array:ArrayCollection, property:Object, value:Object):Number{
   for (var i:Number = 0; i < array.length; i++){
      var obj:Object = Object(array[i])
      if (obj[property] == value)
      return i;
   }
   return -1;
}

//Function for opening dialog for file selection.
public function chooseFiles(event:MouseEvent):void{
    //Set the file filters in the open dialog box and open dialog.
    if (Application.application.parameters.fileFilters == null){
    	var allAllowed:FileFilter = new FileFilter(resourceManager.getString("Resources","AllFiles"),"*.*");
		fileFilters = [allAllowed];
    }else{
    	fileFilters = new Array();
    	var filters:Array = Application.application.parameters.fileFilters.split("||");	
    	for(var i:int=0; i<filters.length; i++){
    		var filter:Array = filters[i].split("|");
    		fileFilters.push(new FileFilter(filter[0], filter[1]));
    	}
    }
    fileReferences.browse(fileFilters);
}

public function isFileAllowed(filetype:String):Boolean{
	for(var i:int=0; i<fileFilters.length; i++){
		var types:Array = FileFilter(fileFilters[i]).extension.split(";");
		if (types.indexOf("*.*")>-1){ return true; }
		if (types.indexOf("*" + filetype)>-1){ return true; }
	}
	return false;
}

//Function to add seleted files to list for upload.
public function addFilesToList(event:Event):void{
    for(var i:int=0; i<fileReferences.fileList.length; i++){
    	if (fileList.length==maxFileNumber){
    		Alert.show(
        		 	StringUtils.Format(resourceManager.getString("Resources","ErrorMaxFileNumber"), [maxFileNumber]), 
        			resourceManager.getString("Resources","Error")
        	);
    		break;
    	}
        var file:FileReference = fileReferences.fileList[i];
        if (getItemIndexByProperty(fileList, "name", file.name)<0){
        	var fileSize:int = Math.round(file.size/1024);
        	
        	//Check type.
        	if (isFileAllowed(file.type)==false){
        		Alert.show(
        		 	resourceManager.getString("Resources","ErrorFileType"), 
        			resourceManager.getString("Resources","Error"));
        		break;
        	} 
        	
        	//Check size.
        	if (fileSize>maxFileSize){
        		Alert.show(
        		 	StringUtils.Format(resourceManager.getString("Resources","ErrorMaxFileSize"), [fileSize, maxFileSize]), 
        			resourceManager.getString("Resources","Error"));
        		break;
        	}  
        	
        	//Add item.
        	fileList.addItem({name: file.name, size: fileSize, object:file, type:file.type});	
        }
    }
    //Set upload button to visible.
    upload.enabled = fileList.length>0;
}

//Function to remove file from list.
public function removeFromList(event:MouseEvent):void{
	fileList.removeItemAt(getItemIndexByProperty(fileList, "name", files.selectedItem.name));
    upload.enabled = fileList.length>0;
}

//Function to remove all files from list.
public function removeAllFromList(event:MouseEvent):void{
	fileList.removeAll();
    upload.enabled = fileList.length>0;
}

//Function for uploading files to server.
public function uploadFiles(event:Event):void{
    //Disable buttons.
    choose.enabled=false;
    upload.enabled=false;
    
	//Upload.
    if(fileList.length > 0){
        for(var i:int=0;i<fileList.length;i++){
            var file:FileReference = fileList[i].object;
            var request:URLRequest = new URLRequest(serviceUrl + "?a=" + folderPath);
            
            file.addEventListener(SecurityErrorEvent.SECURITY_ERROR, uploadSecurityError);
            file.addEventListener(IOErrorEvent.IO_ERROR, uploadIOError);
            file.addEventListener(ProgressEvent.PROGRESS, uploadProgress);
            
            request.contentType = "application/octet-stream";
            request.method = "POST";

            file.upload(request,file.name,false);
        }
    }  

	//Enable buttons.
    choose.enabled=true;
    upload.enabled=fileList.length>0;
}

//Function to show upload progress.
public function uploadProgress(event:ProgressEvent):void{
    var file:FileReference = FileReference(event.target);
    if(event.bytesLoaded==event.bytesTotal){
	 	fileList.removeItemAt(getItemIndexByProperty(fileList, "name", file.name));
    }
    upload.enabled = fileList.length>0;
}

public function uploadSecurityError(event:SecurityErrorEvent):void{
	Alert.show(event.text, resourceManager.getString("Resources","ErrorIO"));
}

public function uploadIOError(event:IOErrorEvent):void{
	Alert.show(event.text, resourceManager.getString("Resources","ErrorSecurity"));
}